package com.version1.diabeco.ui.comida;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import kankan.wheel.widget.OnWheelChangedListener;
import kankan.wheel.widget.WheelView;
import kankan.wheel.widget.adapters.NumericWheelAdapter;
import kankan.wheel.widget.adapters.WheelViewAdapter;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.version1.diabeco.ActivityMain;
import com.version1.diabeco.DateArrayAdapter;
import com.version1.diabeco.DateNumericAdapter;
import com.version1.diabeco.R;
import com.version1.diabeco.data.ajustes.perfilusuario.PerfilUsuarioDaoImpl;
import com.version1.diabeco.data.comida.AlimentoDaoImpl;
import com.version1.diabeco.data.comida.ComidaDaoImpl;
import com.version1.diabeco.model.ajustes.perfilusuario.PerfilUsuario;
import com.version1.diabeco.model.alimento.Alimento;
import com.version1.diabeco.model.comida.Comida;
import com.version1.diabeco.model.comida.DetalleComida;

public class ActivityRegistroComida extends Activity {

	private static final int REQUEST_CODE_ALIMENTO = 1234;
	private static final int REQUEST_CODE_VOICE_RECORDING = 1235;
	public static final String INTENT_VALUE_DETALLE_COMIDA = "DetalleComida";

	private Comida comida;
	private Calendar objCalendario;
	Button btnFecha, btnHora;
	private PerfilUsuario objPerfilUsuario;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_registro_comida);
		
		//Cargamos el Perfil de Usuario de la Base de Datos
		objPerfilUsuario = PerfilUsuarioDaoImpl.getInstance(this).selectUsuarioActivo();
		
		this.cargarPantalla();
	}

	private void cargarPantalla() {
		btnFecha 	  = (Button) findViewById(R.id.btnFecha);
		btnHora 	  = (Button) findViewById(R.id.btnHora);
		objCalendario = Calendar.getInstance();
		
		Comida comida = (Comida) this.getIntent().getSerializableExtra(ActivityListaRegistrosComidas.INTENT_VALUE_COMIDA);
		this.setComida(comida);

		this.cargarSpinnerCuando();
		this.cargarAutocompleteComida();
		this.cargarListaDetalleComida();
		this.cargarBtnFecha(comida.getFecha());
		this.cargarBtnHora(comida.getFecha());

	}

	private void cargarListaDetalleComida() {
		Comida comida = this.getComida();

		ListView listaDetalleComida = (ListView) findViewById(R.id.list_registros_detalle_comida);
		DetalleComidaAdapter detalleComidaAdapter = new DetalleComidaAdapter(this, comida.getDetalleComida());
		listaDetalleComida.setAdapter(detalleComidaAdapter);
		detalleComidaAdapter.notifyDataSetChanged();

    	Long hdcTotal = 0L;
    	
    	for (int i = 0 ; i < listaDetalleComida.getCount() ; i++) {
    		Long hdc = ((DetalleComida) listaDetalleComida.getItemAtPosition(i)).getCarbohidratosAjustados();
    		hdcTotal += hdc;
    	}

    	try { 
    		TextView textViewHdcTotalValor = (TextView) findViewById(R.id.textViewHdcTotalValor);
	    	textViewHdcTotalValor.setText(hdcTotal + "");
    	} catch(Exception e) {
    		System.out.println("Error en la configuracion del HdC total.");
    		e.printStackTrace();
    	}

		if (!comida.getDetalleComida().isEmpty()) {

			listaDetalleComida.setOnItemClickListener(new OnItemClickListener() {
				@Override
				public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

					DetalleComidaAdapter arrayAdapter = (DetalleComidaAdapter) ((ListView) parent).getAdapter();
					DetalleComida detalleComida = arrayAdapter.getItem(position);

					Intent intent = new Intent(parent.getContext(), ActivityRegistroDetalleComida.class);
					intent.putExtra(INTENT_VALUE_DETALLE_COMIDA, detalleComida);
					startActivityForResult(intent, REQUEST_CODE_ALIMENTO);
				}

			});

			listaDetalleComida.setOnItemLongClickListener(new OnItemLongClickListener() {

				public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

					ArrayAdapter<DetalleComida> arrayAdapter = (ArrayAdapter<DetalleComida>) ((ListView) parent)
							.getAdapter();
					DetalleComida detalleComida = arrayAdapter.getItem(position);

					ComidaDaoImpl.getInstance(ActivityRegistroComida.this).deleteDetalleComidaById(detalleComida.getId());

					arrayAdapter.notifyDataSetChanged();

					return true;
				}
			});
		} else {
			// TODO inform the user there are no comidas taken
		}
	}

	private void cargarSpinnerCuando() {
		
		Comida comida = this.getComida();
		
		Spinner spinnerCuando = (Spinner) findViewById(R.id.spinnerComidaCuando);

		if (comida.getId() != null) {
			posicionarSpinnerCuando(spinnerCuando, comida.getCuando());
		}
	}

	private void cargarAutocompleteComida() {
		ArrayAdapter<Alimento> measuresAdapter;
		List<Alimento> alimentos = AlimentoDaoImpl.getInstance(this).selectAll();

		if (!alimentos.isEmpty()) {
			AutoCompleteTextView autoCompleteComida = (AutoCompleteTextView) findViewById(R.id.autoCompleteComida);

			if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
				measuresAdapter = new ArrayAdapter<Alimento>(this,
						R.layout.autocomplete_dropdown_item, alimentos);
			} else {
				measuresAdapter = new ArrayAdapter<Alimento>(this,
						R.layout.autocomplete_dropdown_item2, alimentos);	
			}

			autoCompleteComida.setAdapter(measuresAdapter);
		}
		
	}

	private void posicionarSpinnerCuando(Spinner combo, String cuandoASeleccionar) {

		for (int i = 0; i < combo.getCount(); i++) {
			String cuando = (String) combo.getItemAtPosition(i);

			if (cuando.equals(cuandoASeleccionar)) {
				combo.setSelection(i);
				break;
			}
		}

	}

	public void voiceRecordMeasureAction(View view) {
		Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
		intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
		intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Diabeco");
		startActivityForResult(intent, REQUEST_CODE_VOICE_RECORDING);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == RESULT_OK) {
			if (requestCode == REQUEST_CODE_ALIMENTO) {
	
				DetalleComida detalleComida = (DetalleComida) data.getSerializableExtra(ActivityRegistroComida.INTENT_VALUE_DETALLE_COMIDA);

				this.agregarDetalleComidaAComida(detalleComida);
				
			} else if (requestCode == REQUEST_CODE_VOICE_RECORDING) {

				ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
				String firstMatch = matches.iterator().next();
	
				TextView voiceRecognitionText = (TextView) findViewById(R.id.lbl_voice_recognition_result);
				voiceRecognitionText.setText(firstMatch);
	
				String foodIntakeValue = "";
	
				firstMatch = firstMatch.toLowerCase();
				if (firstMatch.contains("comida ")) {
					foodIntakeValue = firstMatch.substring(firstMatch.indexOf("comida ") + "comida ".length());
				}
	
				EditText measureText = (EditText) findViewById(R.id.editText);
				measureText.setText(foodIntakeValue);

			}
		}

		super.onActivityResult(requestCode, resultCode, data);
	}

	private void agregarDetalleComidaAComida(DetalleComida detalleComida) {
		comida.getDetalleComida().add(detalleComida);
		
		ListView listaDetalleComida = (ListView) findViewById(R.id.list_registros_detalle_comida);
		DetalleComidaAdapter detalleComidaAdapter = new DetalleComidaAdapter(this, comida.getDetalleComida());
		listaDetalleComida.setAdapter(detalleComidaAdapter);
		detalleComidaAdapter.notifyDataSetChanged();

    	Long hdcTotal = 0L;
    	
    	for (int i = 0 ; i < listaDetalleComida.getCount() ; i++) {
    		Long hdc = ((DetalleComida) listaDetalleComida.getItemAtPosition(i)).getCarbohidratosAjustados();
    		hdcTotal += hdc;
    	}

    	try { 
    		TextView textViewHdcTotalValor = (TextView) findViewById(R.id.textViewHdcTotalValor);
	    	textViewHdcTotalValor.setText(hdcTotal + "");
    	} catch(Exception e) {
    		System.out.println("Error en la configuracion del HdC total.");
    		e.printStackTrace();
    	}

	}

	public void agregarAlimentoAction(View view) {

		AutoCompleteTextView autoCompleteComida = (AutoCompleteTextView) findViewById(R.id.autoCompleteComida);
		String alimentoText = autoCompleteComida.getText().toString();
		
		List<Alimento> alimentos = AlimentoDaoImpl.getInstance(this).selectAll();

		for(Alimento alimento : alimentos) {
			if (alimento.getNombre().equals(alimentoText)) {

				DetalleComida detalleComida = new DetalleComida();
				detalleComida.setAlimento(alimento);
				detalleComida.setCarbohidratosAjustados(alimento.getCarbohidratos());

				this.agregarDetalleComidaAComida(detalleComida);
				
				LinearLayout dummyLayout = (LinearLayout) findViewById(R.id.dummyLayout);
				autoCompleteComida.setText("");
				
				dummyLayout.requestFocus();
				
				break;
			}
		}

	}
	
	public void listarAlimentosAction(View view) {

		DetalleComida detalleComida = new DetalleComida();

		Intent intent = new Intent(this, ActivityRegistroDetalleComida.class);
		intent.putExtra(INTENT_VALUE_DETALLE_COMIDA, detalleComida);
		startActivityForResult(intent, REQUEST_CODE_ALIMENTO);

	}

	public void grabarComidaAction(View view) {

		Comida comida = (Comida) this.getIntent().getSerializableExtra(
				ActivityListaRegistrosComidas.INTENT_VALUE_COMIDA);

		Spinner spinnerCuando = (Spinner) findViewById(R.id.spinnerComidaCuando);

		//Pasamos la fecha y la hora
		String strDia = (String) btnFecha.getText();
		String strHora = (String) btnHora.getText();

		Date dia;
		Date hora;
		try {
			dia = ActivityMain.DATE_FORMAT.parse(strDia);
			hora = ActivityMain.TIME_FORMAT.parse(strHora);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(hora);
		int hour = calendar.get(Calendar.HOUR_OF_DAY);
		int minutes = calendar.get(Calendar.MINUTE);

		calendar.setTime(dia);
		calendar.set(Calendar.HOUR, hour);
		calendar.set(Calendar.MINUTE, minutes);
				
		comida.setFecha(calendar.getTimeInMillis());
		
		//Pasamos el Evento
		comida.setCuando(spinnerCuando.getSelectedItem().toString());
		
		//Si se cargaron alimentos grabamos
		if (comida.getDetalleComida().isEmpty() == true) {
			Toast.makeText(this, "Ingrese al menos 1 Alimento", Toast.LENGTH_SHORT).show();			
		} else {
			ComidaDaoImpl.getInstance(this).save(comida);
			Toast.makeText(this, "Comida Guardada", Toast.LENGTH_SHORT).show();
			setResult(Activity.RESULT_OK, this.getIntent());
			finish();

		}

	}

	public void cancelarAction(View view) {
		Toast.makeText(this, "Operacion Cancelada", Toast.LENGTH_SHORT).show();
		this.finish();
	}

	/** Carga la Fecha actual y grisa el campo si recibe la fecha por parametro **/
	void cargarBtnFecha(Long fecha) {
		int intDia, intMes, intAno;

		if (fecha == null) {
			// Agregamos la fecha actual y llamamos al DatePicketDialog
			intDia = objCalendario.get(Calendar.DAY_OF_MONTH);
			intMes = objCalendario.get(Calendar.MONTH) + 1;
			intAno = objCalendario.get(Calendar.YEAR);

			btnFecha.setText(new StringBuilder().append(intDia).append("/").
												 append(intMes).append("/").
												 append(intAno).append(" "));
		} else {
			btnFecha.setText(ActivityMain.DATE_FORMAT.format(new Date(fecha)));
			btnFecha.setEnabled(false);
		}
	}

	
	/** Carga la Hora actual y grisa el campo **/
	void cargarBtnHora(Long hora) {
		int intHora, intMinuto;
		
		if (hora == null) {
			// Agregamos la fecha actual y llamamos al DatePicketDialog
			objCalendario = Calendar.getInstance();
			intHora = objCalendario.get(Calendar.HOUR_OF_DAY);
			intMinuto = objCalendario.get(Calendar.MINUTE);
			
			CharSequence strHora = "", strMinuto = "";			
			if (intHora < 10) {
				strHora = new StringBuilder().append(0).append(intHora);
			} else {
				strHora = new StringBuilder().append(intHora);
			}
			

			if (intMinuto < 10) {
				strMinuto = new StringBuilder().append(0).append(intMinuto);
			} else {
				strMinuto = new StringBuilder().append(intMinuto);
			}
			
			btnHora.setText(new StringBuilder().append(strHora).append(":").append(strMinuto));
		} else {
			btnHora.setText(ActivityMain.TIME_FORMAT.format(new Date(hora)));
			btnHora.setEnabled(false);
		}
	}

	
	/** Se llama al hacer click en el Boton "Hora" */
	public void ClickHora(View v) {
		LayoutInflater inf = LayoutInflater.from(this);

		// Layout que contiene los wheel's
		View view = inf.inflate(R.layout.wheeltime, null);

		// Hora wheel
		final WheelView hours = (WheelView) view.findViewById(R.id.hours);
		hours.setViewAdapter(new NumericWheelAdapter(this, 0, 23));
		hours.setCyclic(true);
		hours.setCurrentItem(objCalendario.get(Calendar.HOUR_OF_DAY));

		// Minutos wheel
		final WheelView mins = (WheelView) view.findViewById(R.id.minutes);
		mins.setViewAdapter(new NumericWheelAdapter(this, 0, 59));
		mins.setCyclic(true);
		mins.setCurrentItem(objCalendario.get(Calendar.MINUTE));

		// Dialogo
		new AlertDialog.Builder(this).setMessage(R.string.titulo_dialogo_hora).setView(view)
				.setPositiveButton(R.string.btn_fijar, new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						CharSequence strHora = "", strMinuto = "";
						
						int hora = hours.getCurrentItem();
						if (hora < 10) {
							strHora = new StringBuilder().append(0).append(hora);
						} else {
							strHora = new StringBuilder().append(hora);
						}
						
						int minuto = mins.getCurrentItem();
						if (minuto < 10) {
							strMinuto = new StringBuilder().append(0).append(minuto);
						} else {
							strMinuto = new StringBuilder().append(minuto);
						}
						btnHora.setText(new StringBuilder().append(strHora).append(":").append(strMinuto));
					}
				})
				.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						return;
					}
				}).create().show();
	}

	
	/** Se llama al hacer click en el Boton "Fecha" */
	public void ClickFecha(View v) {
		LayoutInflater inf = LayoutInflater.from(this);
		Resources res = getResources();
        
		// layout of alert box contains
		View view = inf.inflate(R.layout.wheeldate, null);

		final WheelView month = (WheelView) view.findViewById(R.id.month);
		final WheelView year = (WheelView) view.findViewById(R.id.year);
		final WheelView day = (WheelView) view.findViewById(R.id.day);

		OnWheelChangedListener listener = new OnWheelChangedListener() {
			public void onChanged(WheelView wheel, int oldValue, int newValue) {
				updateDays(year, month, day);
			}
		};

		// month
		int curMonth = objCalendario.get(Calendar.MONTH);
		String months[] = res.getStringArray(R.array.lb_meses);
		month.setViewAdapter(new DateArrayAdapter(this, months, curMonth));
		// month.setCyclic(true);
		month.setCurrentItem(curMonth);
		month.addChangingListener(listener);

		// year
		final int curYear = objCalendario.get(Calendar.YEAR);
		WheelViewAdapter adapter;
		adapter = new DateNumericAdapter(this, curYear - 3, curYear + 10, 3);
		year.setViewAdapter(adapter);
		// year.setCyclic(true);
		year.setCurrentItem(3);
		year.addChangingListener(listener);

		// //day
		updateDays(year, month, day);
		// day.setCyclic(true);
		day.setCurrentItem(objCalendario.get(Calendar.DAY_OF_MONTH) - 1);

		new AlertDialog.Builder(this).setMessage(R.string.titulo_dialogo_fecha).setView(view)
				.setPositiveButton(R.string.btn_fijar, new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						// write code of lines, whatever want to with
						// value of this timepicker
						int dia = day.getCurrentItem() + 1;
						int mes = month.getCurrentItem() + 1;
						int ano = (curYear - 3) + year.getCurrentItem();

						btnFecha.setText(new StringBuilder().append(dia).append("/").append(mes).append("/")
								.append(ano).append(" "));
					}
				})

				.setNegativeButton(R.string.btn_cancelar, new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						return;
					}
				}).create().show();

	}

	/**
	 * Updates day wheel. Sets max days according to selected month and year
	 */
	void updateDays(WheelView year, WheelView month, WheelView day) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + year.getCurrentItem());
		calendar.set(Calendar.MONTH, month.getCurrentItem());

		int maxDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		day.setViewAdapter(new DateNumericAdapter(this, 1, maxDays, calendar.get(Calendar.DAY_OF_MONTH) - 1));
		int curDay = Math.min(maxDays, day.getCurrentItem() + 1);
		day.setCurrentItem(curDay - 1, true);
	}
	
	public Comida getComida() {
		return comida;
	}

	public void setComida(Comida comida) {
		this.comida = comida;
	}

	
}
